/**
 * 
 */
package src.model.gameObject.ability;

import src.model.gameObject.GameObject;
import src.model.gameWorld.LookupTable;
import src.model.gameWorld.Position;
import src.model.gameObject.eventBrokers.HealthEventBroker;
import src.model.gameObject.eventBrokers.MoveEventBroker;
import src.model.gameObject.eventInterfaces.MovePositionListener;
import src.model.gameObject.eventInterfaces.HealthPublisher;
import src.model.gameWorld.ActualMap;

/**
 * <b>Overview</b><br>
 * <p>This class represents the ability of an object to be a "modify health area effect."
 * This includes damageing and healing.</p>
 * <br><br>
 * <b>Responsibilites</b><br>
 * <p>Modify the health of anything that moves over it (that has a Health ability)</p>
 * <br><br>
 * <b>Collaborators</b>
 * <br>ActualMap - To query about its position(for registering and unregistering)<br>
 * <b>Implementor</b> - Tristan Lohman<br>
 * <b>Tester</b> - Tim<br>
 * 
 * 
 * @author Tristan
 *
 */
public class AEModifyHealth extends Ability implements MovePositionListener, HealthPublisher{

	private ActualMap am;
	/**
	 * This constructs a new Area Effect and registers it with the MoveEventBroker.
	 * @param go The GameObject that owns this.
	 * @param am The ActualMap.
	 * @param lookup The LookupTable for this Area Effect.
	 */
	public AEModifyHealth(GameObject go, ActualMap am, LookupTable lookup) {
		super(go, AbilityType.AEMODIFYHEALTH, lookup);
		MoveEventBroker.register(am.findObject(super.gameObject()), this);
		MoveEventBroker.register(super.gameObject(), this);
		this.am = am;
	}

	/**
	 * Notify that something moved onto this, so that this may affect its health (if applicable).
	 * @param go The GameObject that moved onto this.
	 */
	public void notifyPositionMovedOnto(GameObject go){
		publishHealthModifier(go, super.getAttribute(AbilityAttributes.STRENGTH));
	}
	
	public void publishHealthModifier(GameObject go, float modifyAmount){
		src.model.gameObject.eventBrokers.HealthEventBroker.notifyModifyHealth(go, modifyAmount);
	}

	public void destroySub(){
		this.am = null;
		MoveEventBroker.unregister(am.findObject(super.gameObject()), this);
		MoveEventBroker.unregister(super.gameObject(), this);
		HealthEventBroker.unregister(super.gameObject());
	}
	
	/**
	 * Notifies this when its PlayerGameObject has moved, allowing it to notify the MoveEventBroker
	 * to change its location that it listens for. This allows us to have area effects that move.<br>
	 * NOTE: Better design to have MoveEventBroker handle this.
	 * @param p The Position that this Ability's Owner moved to.
	 */
	public void notifyGameObjectMoved(Position p){
		src.model.gameObject.eventBrokers.MoveEventBroker.remapListener(this, p);
	}
}
